package com.logic.landseaserver.models.payment.util;

import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.logic.landseaserver.common.LandeaConstants;
import com.logic.landseaserver.common.util.JsonObjectUtils;
import com.logic.landseaserver.common.util.StringTools;
import com.logic.landseaserver.models.payment.bean.ShiJiPaymentResponse;

/**
 * 
 *
 * 项目名称：system-server</br>
 * 类名称：SignVerifyUtil</br>
 * 类描述：银石签名及验签</br>
 * 创建人：Aaron</br>
 * 创建时间：2017年7月21日 下午8:41:29</br>
 * 
 * @version 1.0
 *
 */
public class ShiJiSignVerifyUtil
{
    private static final Logger LOG = LoggerFactory.getLogger(ShiJiSignVerifyUtil.class);
    
    public final static String SIGN = "Sign";
    
    // 签名
    public static String sign(JsonObject jsObj, String key)
    {
        List<String> list = new ArrayList<String>();
        Set<Entry<String, JsonElement>> set = jsObj.entrySet();
        
        for (Entry<String, JsonElement> entry : set)
        {
            String field = entry.getKey();
            JsonElement value = entry.getValue();
            if (!SIGN.equals(field) && !value.isJsonArray() && StringUtils.isNotEmpty(field))
            {
                String valueStr = value.getAsString();
                if (StringUtils.isNotEmpty(valueStr))
                {
                    list.add(field + "=" + value.getAsString());
                }
            }
        }
        
        list.add("Key=" + key);
        int size = list.size();
        String[] arrayToSort = list.toArray(new String[size]);
        Arrays.sort(arrayToSort);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < size; i++)
        {
            if (i > 0)
            {
                sb.append("&");
            }
            sb.append(arrayToSort[i]);
        }
        String result = sb.toString();
        try
        {
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
            byte[] bytes = messageDigest.digest(result.getBytes(LandeaConstants.UTF8_CHARSET));
            result = Hex.encodeHexString(bytes);
        }
        catch (Exception e)
        {
            // 忽略加密方式和字符集不支持异常
            LOG.error("SignVerifyUtil error|key=" + key + "|" + jsObj.toString(), e);
        }
        return result;
    }
    
    // 验签
    public static boolean verify(JsonObject jsObj, String key)
    {
        JsonElement jsonElementsign = jsObj.get(SIGN);
        if (null == jsonElementsign)
        {
            return false;
        }
        
        String sign = jsonElementsign.getAsString();
        if (StringUtils.isEmpty(sign))
        {
            return false;
        }
        
        return sign.equals(sign(jsObj, key));
    }
    
//    public static void main(String[] args)
//        throws Exception
//    {
//        Map<String, Object> responseMap = new HashMap<String, Object>();
//        responseMap.put("PlatformTxnNo", "818011300668090");
//        responseMap.put("NotifyType", "1");
//        responseMap.put("PayerID", "*");
//        responseMap.put("PayerRealID", "");
//        responseMap.put("TxnReqTime", "2018/01/13 01:50:29");
//        responseMap.put("MerchantRechargeAmt", "0.00");
//        responseMap.put("CashierID", "payall");
//        responseMap.put("PartnerID", "1017");
//        responseMap.put("MerchantID", "200110000003558");
//        responseMap.put("ChannelID", "2");
//        responseMap.put("ChannelDisctAmt", "0.00");
//        responseMap.put("CurrencyCode", "156");
//        responseMap.put("ChannelTxnNo", "4200000077201801133047953089");
//        responseMap.put("MerchantName", "朗诗寓南京新街口店");
//        responseMap.put("TotalAmt", "0.01");
//        responseMap.put("OrgTxnNo", "5973");
//        responseMap.put("TerminalID", "*");
//        responseMap.put("IncomeAmt", "0.01");
//        responseMap.put("MerchantDisctAmt", "0.00");
//        responseMap.put("PointAmt", "0.00");
//        responseMap.put("Sign", "c8483ab229c25c38744ea6f0f6899b8e8f2af2672017fab52b4ed6cd95671c98");
//        responseMap.put("InvoiceAmt", "0.01");
//
//        if (!ShiJiSignVerifyUtil.verify(JsonObjectUtils.map2JsonObject(responseMap), "t0egmimvup5qppo52idr"))
//        {
//            System.out.println(1);
//        }
//    }
    
    public static ShiJiPaymentResponse buildResponseFromRespMap(Map<String, Object> responseMap)
    {
        ShiJiPaymentResponse shiJiPaymentResponse = new ShiJiPaymentResponse();
        
        shiJiPaymentResponse.setPlatformTxnNo(StringTools.getString(responseMap.get("PlatformTxnNo")));
        shiJiPaymentResponse.setNotifyType(StringTools.getString(responseMap.get("NotifyType")));
        shiJiPaymentResponse.setPayerID(StringTools.getString(responseMap.get("PayerID")));
        shiJiPaymentResponse.setTxnReqTime(StringTools.getString(responseMap.get("TxnReqTime")));
        shiJiPaymentResponse.setPartnerID(StringTools.getString(responseMap.get("PartnerID")));
        shiJiPaymentResponse.setMerchantID(StringTools.getString(responseMap.get("MerchantID")));
        shiJiPaymentResponse.setChannelID(StringTools.getString(responseMap.get("ChannelID")));
        shiJiPaymentResponse.setChannelDisctAmt(StringTools.getString(responseMap.get("ChannelDisctAmt")));
        shiJiPaymentResponse.setCurrencyCode(StringTools.getString(responseMap.get("CurrencyCode")));
        shiJiPaymentResponse.setChannelTxnNo(StringTools.getString(responseMap.get("ChannelTxnNo")));
        shiJiPaymentResponse.setMerchantName(StringTools.getString(responseMap.get("MerchantName")));
        shiJiPaymentResponse.setTotalAmt(StringTools.getString(responseMap.get("TotalAmt")));
        shiJiPaymentResponse.setOrgTxnNo(StringTools.getString(responseMap.get("OrgTxnNo")));
        shiJiPaymentResponse.setTerminalID(StringTools.getString(responseMap.get("TerminalID")));
        shiJiPaymentResponse.setIncomeAmt(StringTools.getString(responseMap.get("IncomeAmt")));
        shiJiPaymentResponse.setMerchantDisctAmt(StringTools.getString(responseMap.get("MerchantDisctAmt")));
        shiJiPaymentResponse.setPointAmt(StringTools.getString(responseMap.get("PointAmt")));
        shiJiPaymentResponse.setSign(StringTools.getString(responseMap.get("Sign")));
        shiJiPaymentResponse.setInvoiceAmt(StringTools.getString(responseMap.get("nvoiceAmt")));
        shiJiPaymentResponse.setOrgOrderNo(StringTools.getString(responseMap.get("OrgOrderNo")));
        
        shiJiPaymentResponse.setRespCode(StringTools.getString(responseMap.get("RespCode")));
        shiJiPaymentResponse.setRespDesc(StringTools.getString(responseMap.get("RespDesc")));
        
        // 将map保存，后续有用
        shiJiPaymentResponse.setResponseMap(responseMap);
        
        return shiJiPaymentResponse;
    }
}
